/**
 * Copyright (C) 2009 Noel Ang
 *
 * This file is part of Samsara.
 *
 * Samsara is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Samsara is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Samsara.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
package com.lunarshades.samsara.ui.actions;

import java.util.LinkedHashSet;
import java.util.Set;
import javax.swing.AbstractAction;

import com.lunarshades.samsara.Raider;

/**
 * Provides support of managing KarmaChangeListeners and dispatching
 * KarmaChangeEvents.
 *
 * @author Noel Ang, sparta.variable@gmail.com
 */
public abstract class KarmaChangeAction extends AbstractAction {

protected KarmaChangeAction() {
    super();
    mListeners = new LinkedHashSet<KarmaChangeListener>();
}

protected KarmaChangeAction(String name) {
    super(name);
    mListeners = new LinkedHashSet<KarmaChangeListener>();
}

public void addKarmaChangeListener(KarmaChangeListener listener) {
    if (listener == null) {
        throw new NullPointerException();
    }
    synchronized (mListeners) {
        mListeners.add(listener);
    }
}

public void removeKarmaChangeListener(KarmaChangeListener listener) {
    synchronized (mListeners) {
        mListeners.remove(listener);
    }
}

public <E extends Raider> void fireKarmaAdded(E subject, int amountAdded) {
    final KarmaAddEvent EVENT = new KarmaAddEvent<E>(subject, amountAdded, null
    );
    synchronized (mListeners) {
        for (KarmaChangeListener listener : mListeners) {
            listener.karmaChanged(EVENT);
        }
    }
}

public <E extends Raider> void fireKarmaRemoved(E subject, int amountRemoved) {
    final KarmaSubtractEvent EVENT = new KarmaSubtractEvent<E>(subject,
            amountRemoved,
            null
    );
    synchronized (mListeners) {
        for (KarmaChangeListener listener : mListeners) {
            listener.karmaChanged(EVENT);
        }
    }
}

public <E extends Raider> void fireKarmaContestWon(E subject,
                                                   Set<E> others,
                                                   int karmaRemoved,
                                                   String comment
) {
    final ContestWinEvent EVENT = new ContestWinEvent<E>(subject,
            others,
            karmaRemoved,
            comment
    );
    synchronized (mListeners) {
        for (KarmaChangeListener listener : mListeners) {
            listener.karmaChanged(EVENT);
        }
    }
}

public <E extends Raider> void fireKarmaStatus(E subject) {
    final KarmaStatusEvent EVENT = new KarmaStatusEvent<E>(subject);
    synchronized (mListeners) {
        for (KarmaChangeListener listener : mListeners) {
            listener.karmaChanged(EVENT);
        }
    }
}

private final Set<KarmaChangeListener> mListeners;
}
